/*
 * Alloy Analyzer
 * Copyright (c) 2004 Massachusetts Institute of Technology
 *
 * The Alloy Analyzer is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * The Alloy Analyzer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the Alloy Analyzer; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package alloy.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JWindow;
import javax.swing.Timer;

import alloy.util.ResourceManager;

class AlloySplashScreen extends JWindow {
    final int INITIALDELAY = 2000;
    final String TEXTFILE = "splash.txt";
    final ImageIcon ALLOY_ICON = 
	new ImageIcon(AlloySwingUtilities.loadImage("images/alloylogo.gif"));
    /** Display Alloy splash screen, and disable owner.  Splash will
     *  disappear and owner will be reenabled when user clicks anywhere
     *  on splash screen
     */
    static void splash(Window owner) {
	new AlloySplashScreen(owner);
    }

    private AlloySplashScreen(final Window owner) {
	super(owner);
	owner.setEnabled(false);

	// read scrolling text from file
	String scrollText;
	try {
	    InputStream in = 
		ResourceManager.getResourceAsStream(TEXTFILE);
	    OutputStream out = new ByteArrayOutputStream();

	    while (true) {
		int b = in.read();
		if (b == -1) break;
		out.write(b);
	    }

	    scrollText = out.toString();
	} catch (IOException ex) {
	    scrollText = "ERROR: could not read splash screen text from "
		+ TEXTFILE;
	}

	JLabel logo = new JLabel("alloy analyzer version 3.0",
 				 ALLOY_ICON,
				 JLabel.CENTER);
	logo.setHorizontalTextPosition(JLabel.CENTER);
	logo.setVerticalTextPosition(JLabel.BOTTOM);
	logo.setFont(logo.getFont().deriveFont((float)36));
	logo.setAlignmentX(JLabel.CENTER_ALIGNMENT);
	logo.setOpaque(true);
	logo.setBackground(Color.white);

	Dimension logoSize = logo.getPreferredSize();

	final Scroller scroller = new Scroller(scrollText,7,INITIALDELAY,1,100);
	scroller.setBorder(BorderFactory.createMatteBorder(10,10,0,10,
							   Color.white));


	Box mainBox = Box.createVerticalBox();
	mainBox.add(logo);
	mainBox.add(scroller);
	JPanel mainPanel = new JPanel(new BorderLayout());
	mainPanel.add(mainBox, BorderLayout.CENTER);
	mainPanel.setBorder(BorderFactory.createCompoundBorder
			    (AlloySwingUtilities.onMac() ? null :
			     BorderFactory.createLineBorder(Color.black, 1),
			     BorderFactory.createMatteBorder(20,20,20,20,
							     Color.white)));

	getGlassPane().setVisible(true);
	getGlassPane().addMouseListener(new MouseAdapter() {
		public void mouseClicked(MouseEvent e) {
		    setVisible(false);
		    scroller.stop();
		    owner.setEnabled(true);
		    dispose();
		}
	    });

	getContentPane().add(mainPanel, BorderLayout.CENTER);
	pack();
	setLocation((AlloySwingUtilities.getScreenWidth()-getWidth())/2,
		    (AlloySwingUtilities.getScreenHeight()-getHeight())/2);
	show();
	scroller.start();
    }
}

// Component that displays continuously scrolling text
class Scroller extends JPanel {
    private int offset;
    private Timer timer;

    /** Create a Scroller which displays the given text in a loop.  
     *  There will be visibleLines lines of text in view at a time.
     *  (NOTE: The Scroller may not display correctly if the entire text 
     *   takes up fewer than visibleLines lines.)
     *  After initially remaining still for initialDelay milliseconds,
     *  the text scrolls upward by step pixels every delay milliseconds.
     */

    Scroller(String text, int visibleLines, 
	     int initialDelay, final int step, int delay) {
	super(new BorderLayout());

	// Two identical JTextArea objects are lined up vertically inside 
	// innerPane, and the timer gradually shifts the location of
	// the text areas upwards within innerPane, giving the appearance
	// of a circular scrolling loop.

	final JTextArea area1 = new JTextArea(text);
	final JTextArea area2 = new JTextArea(text);
	area1.setEditable(false);
	area1.setLineWrap(true);
	area1.setWrapStyleWord(true);
	// this makes a line between the end of the text and the
	// beginning of the next cycle of the text
	area1.setBorder(BorderFactory.createMatteBorder(0,0,1,0,Color.black));

	area2.setEditable(false);
	area2.setLineWrap(true);
	area2.setWrapStyleWord(true);

	JPanel innerPane = new JPanel();
	innerPane.setLayout(new BoxLayout(innerPane, BoxLayout.Y_AXIS));
	innerPane.add(area1);
	innerPane.add(area2);
	innerPane.setPreferredSize(new Dimension(innerPane.getPreferredSize().width,
						 visibleLines * area1.getFontMetrics(getFont()).getHeight()));

	timer = new Timer(delay,
			  new ActionListener() {
			      public void actionPerformed(ActionEvent e) {
				  int x = area1.getX();
				  int h = area1.getHeight();
				  offset += step;
				  offset %= h;
				  area1.setLocation(x, -offset);
				  area2.setLocation(x, h-offset);
			      }
			  });
	timer.setInitialDelay(initialDelay);
	timer.setCoalesce(true);

	add(innerPane);
    }

    public void start() {
	timer.start();
    }

    public void stop() {
	timer.stop();
    }
}
